package middleware

import (
	"enzyme-backend/core/utils"
	"net/http"
	"strings"

	"github.com/gin-gonic/gin"
)

// CORS 中间件处理跨域请求
func CORS() gin.HandlerFunc {
	return func(c *gin.Context) {
		c.Header("Access-Control-Allow-Origin", "*")
		c.Header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
		c.Header("Access-Control-Allow-Headers", "Origin, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, X-Forwarded-For, Host, X-Enzyme-Device-Fingerprint, X-Enzyme-Unique-Unique-ID")
		c.Header("Access-Control-Expose-Headers", "Content-Length")
		c.Header("Access-Control-Allow-Credentials", "true")

		if c.Request.Method == "OPTIONS" {
			c.AbortWithStatus(http.StatusNoContent)
			return
		}

		c.Next()
	}
}

// getClientIP 获取客户端真实IP地址
func getClientIP(c *gin.Context) string {
	// 优先从X-Forwarded-For获取真实IP
	if forwardedFor := c.GetHeader("X-Forwarded-For"); forwardedFor != "" {
		// X-Forwarded-For可能包含多个IP，取第一个
		ips := strings.Split(forwardedFor, ",")
		if len(ips) > 0 {
			ip := strings.TrimSpace(ips[0])
			if ip != "" {
				return ip
			}
		}
	}

	// 如果没有X-Forwarded-For，使用Host请求头
	if host := c.GetHeader("Host"); host != "" {
		// 从Host中提取IP地址（去掉端口号）
		if colonIndex := strings.Index(host, ":"); colonIndex > 0 {
			return host[:colonIndex]
		}
		return host
	}

	// 最后使用RemoteAddr
	return c.ClientIP()
}

// ValidateHeaders 验证必需的请求头
func ValidateHeaders() gin.HandlerFunc {
	return func(c *gin.Context) {
		if strings.HasPrefix(c.Request.URL.Path, "/proxy") {
			c.Next()
			return
		}

		// 获取请求头
		ip := getClientIP(c)
		fingerprint := c.GetHeader("X-Enzyme-Device-Fingerprint")
		// fingerprint = "chrome"
		token := c.GetHeader("X-Enzyme-Token")

		// 检查IP和Fingerprint是否为空
		if strings.TrimSpace(fingerprint) == "" {
			utils.GlobalLogger.Error("X-Enzyme-Device-Fingerprint不能为空")
			c.JSON(http.StatusBadRequest, gin.H{
				"error": "X-Enzyme-Device-Fingerprint不能为空",
			})
			c.Abort()
			return
		}

		// 将请求头信息存储到上下文中，供后续处理器使用
		c.Set("ip", ip)
		c.Set("fingerprint", fingerprint)
		c.Set("token", token)
		utils.GlobalLogger.Info("ValidateHeaders: %s, %s, %s", ip, fingerprint, token)
		c.Next()
	}
}
